﻿using System.Collections.Generic;

namespace Ndns.Packet.Abstractions
{
    public class DnsPacket
    {

        /// <summary>
        /// 表示DNS数据包的编号。
        /// </summary>
        public ushort TransactionID { get; set; }

        #region Flags相关

        /// <summary>
        /// 表示DNS数据包的特征标志。
        /// </summary>
        public DnsPacketFlag Flag
        {
            get { return _flag; }
            set { _flag = value; }
        }
        private DnsPacketFlag _flag = DnsPacketFlag.RecursionDesired;


        public bool IsResponsePacket
        {
            get { return (_flag & DnsPacketFlag.ResponsePacket) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.ResponsePacket));
                if (value) _flag = _flag | DnsPacketFlag.ResponsePacket;
            }
        }

        public bool ServerAuthoritative
        {
            get { return (_flag & DnsPacketFlag.ServerAuthoritative) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.ServerAuthoritative));
                if (value) _flag = _flag | DnsPacketFlag.ServerAuthoritative;
            }
        }

        public bool Truncated
        {
            get { return (_flag & DnsPacketFlag.Truncated) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.Truncated));
                if (value) _flag = _flag | DnsPacketFlag.Truncated;
            }
        }

        public bool RecursionDesired
        {
            get { return (_flag & DnsPacketFlag.RecursionDesired) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.RecursionDesired));
                if (value) _flag = _flag | DnsPacketFlag.RecursionDesired;
            }
        }

        public bool RecursionAvailable
        {
            get { return (_flag & DnsPacketFlag.RecursionAvailable) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.RecursionAvailable));
                if (value) _flag = _flag | DnsPacketFlag.RecursionAvailable;
            }
        }

        public bool AnswerAuthenticated
        {
            get { return (_flag & DnsPacketFlag.AnswerAuthenticated) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.AnswerAuthenticated));
                if (value) _flag = _flag | DnsPacketFlag.AnswerAuthenticated;
            }
        }

        public bool AcceptNonAuthenticatedData
        {
            get { return (_flag & DnsPacketFlag.AcceptNonAuthenticatedData) > 0; }
            set
            {
                _flag = (_flag & (DnsPacketFlag)(DnsPacketFlag.MaxValue - DnsPacketFlag.AcceptNonAuthenticatedData));
                if (value) _flag = _flag | DnsPacketFlag.AcceptNonAuthenticatedData;
            }
        }

        /// <summary>
        /// 获取/设置Flag中的操作码字段。
        /// </summary>
        public DnsOpCode OpCode
        {
            get { return (DnsOpCode)(((ushort)_flag & 0x7800) >> 11); }
            set { _flag = (DnsPacketFlag)((ushort)_flag & 0x87ff | (((byte)value & 0xf) << 11)); }
        }

        /// <summary>
        /// 获取/设置Flag中的回复码字段。
        /// </summary>
        public DnsReplyCode ReplyCode
        {
            get { return (DnsReplyCode)((ushort)_flag & 0xf); }
            set { _flag = (DnsPacketFlag)((ushort)_flag & 0xfff0 | ((byte)value & 0xf)); }
        }

        #endregion

        #region 记录

        /// <summary>
        /// 数据包中包含的查询项。
        /// </summary>
        public IList<DnsQuery> Queries => _queries;

        /// <summary>
        /// 数据包中包含的应答记录。
        /// </summary>
        public IList<DnsResourceRecord> AnswerRRs => _answerRRs;

        /// <summary>
        /// 数据包中包含的权威命名服务器的记录。
        /// </summary>
        public IList<DnsResourceRecord> AuthoritativeNSs => _authoritativeNSs;

        /// <summary>
        /// 数据包中包含的附加记录。
        /// </summary>
        public IList<DnsResourceRecord> AdditionalRRs => _additionalRRs;

        private List<DnsQuery> _queries = new List<DnsQuery>();
        private List<DnsResourceRecord> _answerRRs = new List<DnsResourceRecord>();
        private List<DnsResourceRecord> _authoritativeNSs = new List<DnsResourceRecord>();
        private List<DnsResourceRecord> _additionalRRs = new List<DnsResourceRecord>();
        #endregion

        #region 实例构造

        /// <summary>
        /// 以默认属性构造DnsPacket实例。
        /// </summary>
        public DnsPacket()
        {

        }

        /// <summary>
        /// 构造DnsPacket实例，并设置TransactionID和DNS标志。
        /// </summary>
        /// <param name="transactionID">要设置的TransactionID属性。</param>
        /// <param name="flag">DNS标志</param>
        public DnsPacket(ushort transactionID, DnsPacketFlag flag)
        {
            TransactionID = transactionID;
            _flag = flag;
        }


        #endregion

    }
}
